import { jl3D,jl2D } from "./jl";
import { qpTx } from "./ui";
const meshScale = 1/16;

// 1. 同时导入 JSON 数据和它的“数据契约”
import allZsItems from "./gamedata/zswq.json";
// import type { ItemData } from "../types";
import type { ZswqData } from "./types"; // 确保 types.ts 存在于 src 目录下并导出 ItemData

// 2. 创建一个道具数据库，方便通过 ID 快速查找
//    我们用 Map 来存储，键是道具 ID，值是道具数据。
const itemDatabase = new Map<string, ZswqData>();

// 3. 遍历导入的 JSON 数组，填充数据库
//    我们在这里使用 `as ItemData[]` 进行类型断言，
//    意思是告诉 TypeScript：“请相信我，这个 allItems 数组里的每个成员，都符合 ItemData 这个契约”。
//    如果 JSON 文件中的某个字段写错了（比如把 name 写成了 Name），TypeScript 在这里可能不会报错，
//    但在后续使用时，错误依然会被捕捉到。
for (const item of allZsItems as ZswqData[]) {
  // Ensure id is a string for the Map key
  itemDatabase.set(String(item.id), { ...item, id: String(item.id) });
}
// 这样，我们就有了一个类型安全的道具数据库，

// 4. 创建一个函数来获取道具数据

/**
 * 获取指定 ID 的道具数据
 * @param itemId 道具的唯一标识符
 * @returns 指定 ID 的道具数据
 */
export function getZsItem(itemId: string): ZswqData | undefined {
  return itemDatabase.get(itemId);
}


// 计算实体的绝对坐标bounds
function getEntityBounds(entity:GameEntity) {
    const lo = entity.position.sub(entity.bounds);
    const hi = entity.position.add(entity.bounds);
    const bounds = new GameBounds3(lo, hi);
    return bounds;
}

/**
 * 使用主手武器进行攻击
 * @param entity 使用武器的玩家
 * @param wqId 使用的武器ID
 * @param raycast 射线信息
 * @param rotation 视角信息（暂时没用写上就行）
 * @returns 
 */
export async function useZswq(entity:GamePlayerEntity,wqId:number,raycast: GameRaycastResult,rotation: { yaw: number, pitch: number }) {
    if (!entity.canAttack){
        console.warn("error:can't attack!");
        return; 
    } 
    /*
    if (jl3D(entity.position,raycast.hitPosition)>20){
        console.warn("error:jl3D is too long!");
        return;
    }
    */
    //entity.canAttack = false;

    const zswqs=getZsItem(String(wqId));
    if (!zswqs){
        console.warn("error:can't find zswq by id:"+wqId);
        return;
    }
    console.log(entity.player.name+"...attack! id:"+wqId);
    entity.canAttack = false;
    if (zswqs.attackType === 'bodyNear'){
        const jq=world.createEntity({
            mesh: zswqs.attackMesh,
            meshScale: new GameVector3(meshScale*zswqs.attackMeshScale.x,meshScale*zswqs.attackMeshScale.y,meshScale*zswqs.attackMeshScale.z),
            position: entity.position,
            collides: false,
            fixed: false,
            gravity: false,
        })
        const motion = jq.motion.loadByName(zswqs.attackMotion); 
        //motion.onFinish(()=>{
        //    motion.play();
        //})
        motion.play();
        //qpTx('这一切，不过只是雷光闪现的瞬间！', entity);
        // 计算攻击范围
        
        const {interval: damageInterval, bounder: attackBounder} = getDamageInterval(entity, jq, zswqs);

        entity.player.disableInputDirection = GameInputDirection.BOTH;
        zswqs.playerControl.forEach((x)=>{
                entity.player[x.type] = x.after;
            })
            setTimeout(() => {
                clearInterval(damageInterval);
                jq.destroy();
                attackBounder?.destroy();
                entity.player.disableInputDirection = GameInputDirection.NONE;
                zswqs.playerControl.forEach((x)=>{
                    entity.player[x.type] = x.once;
                })
            }, zswqs.attackTime);
            setTimeout(() => {
                entity.canAttack = true;
            }, zswqs.attackCoolingTime);
        
    }else if (zswqs.attackType === 'raycast'){
        if (jl3D(entity.position,raycast.hitPosition)>20){
            console.warn("error:jl3D is too long!");
            return;
        }
        console.log(entity.player.name+"...attack! id:"+wqId);
        entity.canAttack = false;
        const jq=world.createEntity({
            mesh: zswqs.attackMesh,
            meshScale: new GameVector3(meshScale*zswqs.attackMeshScale.x,meshScale*zswqs.attackMeshScale.y,meshScale*zswqs.attackMeshScale.z),
            position: raycast.hitPosition,
            collides: false,
            fixed: false,
            gravity: false,
        })
        const motion = jq.motion.loadByName('attack4s'); 
        //motion.onFinish(()=>{
        //    motion.play();
        //})
        motion.play();
        const {interval: damageInterval, bounder: attackBounder} = getDamageInterval(entity, jq, zswqs);

        zswqs.playerControl.forEach((x)=>{
                entity.player[x.type] = x.after;
            })
        setTimeout(() => {
            clearInterval(damageInterval);
            jq.destroy();
            attackBounder.destroy();
            zswqs.playerControl.forEach((x)=>{
                    entity.player[x.type] = x.once;
                })
        }, zswqs.attackTime);
        setTimeout(() => {
            entity.canAttack = true;
        }, zswqs.attackCoolingTime);
    }
    
    
}


function getDamageInterval(entity: GamePlayerEntity, jq: GameEntity, zswqs: ZswqData) {
    if (zswqs.attackWays === 'radius'){
        const damageInterval = setInterval(() => {
            jq.position.copy(entity.position);
            const damage = zswqs.attackBasicDamage + entity.level * zswqs.attackLevelAdd;
            // 搜索范围 
            
            world.querySelectorAll('.canhurt').forEach((e) => {
                // 在区域的实体
                if (
                    e !== entity &&
                    !e.player &&
                    typeof zswqs.attackRange === 'number' &&
                    jl2D(e.position, entity.position) < zswqs.attackRange &&
                    Math.abs(e.position.y - entity.position.y) < 8
                ) {
                    e.takeDamage_by_player(damage, entity);
                }
            });
        }, 200);
        return {interval: damageInterval, bounder: null};
    }
    else if (zswqs.attackWays === 'zone'){
        
        let rangeX = 1, rangeY = 1, rangeZ = 1;
        if (typeof zswqs.attackRange === 'object' && zswqs.attackRange !== null && 'x' in zswqs.attackRange) {
            rangeX = (zswqs.attackRange as GameVector3).x;
            rangeY = (zswqs.attackRange as GameVector3).y;
            rangeZ = (zswqs.attackRange as GameVector3).z;
        } else if (typeof zswqs.attackRange === 'number') {
            rangeX = rangeY = rangeZ = zswqs.attackRange as number;
        }
        const attackBounder=world.createEntity({
            mesh: 'mesh/单元方块.vb',
            meshScale: new GameVector3(meshScale*rangeX, meshScale*rangeY, meshScale*rangeZ),
            position: jq.position,
            collides: false,
            fixed: false,
            gravity: false,
        })
        if (!zswqs.showAttackRange) attackBounder.meshColor = new GameRGBAColor(0,0,0,0);
        const bounds = getEntityBounds(attackBounder);
        // 使用 forEach 遍历实体列表，输出玩家的名称。
        const damageInterval = setInterval(() => {

            const damage = zswqs.attackBasicDamage+entity.level*zswqs.attackLevelAdd;
            // 搜索范围 
            
            world.searchBox(bounds).forEach( (e) => {
                // 在区域的实体
                if (e.hasTag('canhurt') && e!==entity && !e.player) {
                    e.takeDamage_by_player(damage,entity);
                }
            });
        }, 200);

        return {interval: damageInterval, bounder: attackBounder};
    }
}






/*
// 创建伤害区域模型
function createDamageZone(position: GameVector3, rotation: { yaw: number, pitch: number }) {
    const model = world.createEntity({
        mesh: 'mesh/剑气.vb',
        position: position.clone()
    });

    // 计算前向方向向量
    const forward = new GameVector3(
        Math.cos(rotation.yaw) * Math.cos(rotation.pitch),
        Math.sin(rotation.pitch),
        Math.sin(rotation.yaw) * Math.cos(rotation.pitch)
    );
    
    // 设置模型朝向
    model.lookAt(
        position.clone().add(forward),
        'Y',
        new GameVector3(0, 1, 0)
    );
    return model;
}

// 监听左键按下事件
player.onPress((event) => {
    if (event.button === GameButtonType.ACTION0) {
        // 获取摄像机参数
        const cameraParams = {
            position: event.entity.cameraPosition,
            yaw: event.entity.cameraYaw,
            pitch: event.entity.cameraPitch
        };

        // 创建伤害区域
        const damageZone = createDamageZone(cameraParams.position, {
            yaw: cameraParams.yaw,
            pitch: cameraParams.pitch
        });

        // 设置定时伤害
        const damageInterval = setInterval(() => {
            world.querySelectorAll('*').forEach(entity => {
                if (entity !== damageZone && 
                    entity.position.distanceTo(damageZone.position) < 5) {
                    entity.takeDamage(10); // 假设存在扣血方法
                }
            });
        }, 500);

        // 5秒后销毁
        setTimeout(() => {
            clearInterval(damageInterval);
            damageZone.destroy();
        }, 5000);
    }
});
*/